﻿#include <graphics.h>
#include <conio.h>
#include <stdio.h>
#include <windows.h>
#include <vector> 
#include <ctime> 

using namespace std; // 新增：使用std命名空间

enum EnemyType {
    ENEMY_SMALL,
    ENEMY_MIDDLE,
    ENEMY_BIG
};

bool gameOver = false;
bool playerDying = false;
int playerDeathFrame = 0;

const int PLAYER_SPEED = 5; // 新增：玩家移动速度
// 新增：子弹移动速度常量
const int BULLET_SPEED = 10;
// 新增：最大子弹数量常量
const int MAX_BULLETS = 15;
const int MAX_ENEMIES = 10; // 新增：最大敌机数量

const int MAX_EXPLOSIONS = 10;
// 新增：子弹冷却计时器变量
int bulletTimer = 0;
int enemySpawnTimer = 0; // 新增：敌机生成计时器

int score = 0; // 新增：游戏得分

// 游戏窗口尺寸
const int WIDTH = 480;
const int HEIGHT = 700;

int enemyWidth, enemyHeight; // 新增：敌机尺寸
int playerX, playerY;
int playerWidth,playerHeight;
int bulletWidth, bulletHeight;

// 图像资源
IMAGE img_background;
IMAGE img_player; // 新增：玩家飞机图片
// 新增：子弹图片
IMAGE img_bullet;
IMAGE img_enemy_small, img_enemy_middle, img_enemy_big;

// 爆炸效果图片数组
IMAGE img_explosion_small[4];    // 小型敌机爆炸
IMAGE img_explosion_middle[4];   // 中型敌机爆炸
IMAGE img_explosion_big[6];      // 大型敌机爆炸
IMAGE img_player_death[4];       // 玩家死亡动画

struct Bullet {
    int x;        // 子弹X坐标
    int y;        // 子弹Y坐标
    bool alive;   // 子弹是否激活
};//试着改造成类的方式，使用默认构造函数
struct Enemy {
    int x, y;
    bool alive;
    int speed;
    int type;   // 敌机类型
    int hp;     // 生命值
    int width;  // 宽度
    int height; // 高度
};

// 爆炸效果结构体
struct Explosion {
    int x, y;       // 爆炸位置
    int frame;       // 当前帧数
    bool active;     // 是否激活
    int type;        // 类型（敌机或玩家）
};


// 新增：子弹数组
vector<Bullet> bullets(MAX_BULLETS);
// 新增：敌机数组
vector<Enemy> enemies(MAX_ENEMIES);

vector<Explosion> explosions(MAX_EXPLOSIONS); // 爆炸效果数组

// 函数声明
void initGame();
void loadResources();
void processInput();
void updateGame();
void renderGame();
void checkBoundaries();
void drawAlpha(IMAGE* picture, int picture_x, int picture_y);
// 新增：子弹初始化函数
void initBullets();
void initEnemies();
void spawnEnemy();
void updateEnemies();
void checkCollisions();
void updateExplosions();
void spawnExplosion(int x, int y, int type);
void checkPlayerHit();

int main()
{
    srand((unsigned)time(NULL)); // 新增：初始化随机数种子
    // ==== 游戏初始化 ====
    initGame();

    // ==== 加载游戏资源 ====
    loadResources();

    // 启用双缓冲绘图
    BeginBatchDraw();

    // ==== 游戏主循环 ====
    while (true)
    {
        processInput();    // 处理用户输入
        updateGame();      // 更新游戏状态
        checkBoundaries(); // 边界检查
        checkCollisions(); // 新增：碰撞检测
        checkPlayerHit();
        renderGame();      // 渲染游戏画面

        // 控制游戏帧率
        Sleep(20);

        // 检测ESC键按下退出游戏
        if (GetAsyncKeyState(VK_ESCAPE))
            break;
    }


    return 0;
}


// ==== 游戏初始化 ====
void initGame()
{
    // 初始化游戏窗口
    initgraph(WIDTH, HEIGHT);

    playerX = WIDTH / 2 - 102 / 2;
    playerY = HEIGHT - 126;

    initBullets();
    initEnemies(); // 新增：初始化敌机

    for (int i = 0; i < MAX_EXPLOSIONS; i++) {
        explosions[i].active = false;
    }
}

// ==== 加载资源 ====
void loadResources()
{
    // 加载背景图片
    loadimage(&img_background, "../images/background.png", WIDTH, HEIGHT);
    // 新增：加载玩家飞机图片
    loadimage(&img_player, "../images/me.png", 0, 0);
    playerWidth = img_player.getwidth();
    playerHeight = img_player.getheight();

    // 新增：加载子弹图片并获取尺寸
    loadimage(&img_bullet, "../images/bullet.png");
    bulletWidth = img_bullet.getwidth();
    bulletHeight = img_bullet.getheight();

    // 替换单张敌机图片为多种敌机图片
    loadimage(&img_enemy_small, "../images/enemy1.png");
    loadimage(&img_enemy_middle, "../images/enemy2.png");
    loadimage(&img_enemy_big, "../images/enemy3.png");

    loadimage(&img_explosion_small[0], "../images/enemy1_down1.png");
    loadimage(&img_explosion_small[1], "../images/enemy1_down2.png");
    loadimage(&img_explosion_small[2], "../images/enemy1_down3.png");
    loadimage(&img_explosion_small[3], "../images/enemy1_down4.png");

    // 中型敌机爆炸
    loadimage(&img_explosion_middle[0], "../images/enemy2_down1.png");
    loadimage(&img_explosion_middle[1], "../images/enemy2_down2.png");
    loadimage(&img_explosion_middle[2], "../images/enemy2_down3.png");
    loadimage(&img_explosion_middle[3], "../images/enemy2_down4.png");

    // 大型敌机爆炸
    loadimage(&img_explosion_big[0], "../images/enemy3_down1.png");
    loadimage(&img_explosion_big[1], "../images/enemy3_down2.png");
    loadimage(&img_explosion_big[2], "../images/enemy3_down3.png");
    loadimage(&img_explosion_big[3], "../images/enemy3_down4.png");
    loadimage(&img_explosion_big[4], "../images/enemy3_down5.png");
    loadimage(&img_explosion_big[5], "../images/enemy3_down6.png");

    // 玩家死亡动画
    loadimage(&img_player_death[0], "../images/me_destroy_1.png");
    loadimage(&img_player_death[1], "../images/me_destroy_2.png");
    loadimage(&img_player_death[2], "../images/me_destroy_3.png");
    loadimage(&img_player_death[3], "../images/me_destroy_4.png");
}

// ==== 处理用户输入 ====
void processInput()
{
    if (gameOver) {
        // 游戏结束后按R键重新开始
        if (GetAsyncKeyState('R')) {
            gameOver = false;
            playerDying = false;
            playerDeathFrame = 0;
            score = 0;
            // 重置玩家位置
            playerX = WIDTH / 2 - 40;
            playerY = HEIGHT - 100;

            // 重置所有敌机
            for (int i = 0; i < MAX_ENEMIES; i++) {
                enemies[i].alive = false;
            }

            // 重置所有子弹
            for (int i = 0; i < MAX_BULLETS; i++) {
                bullets[i].alive = false;
            }

            // 重置爆炸效果
            for (int i = 0; i < MAX_EXPLOSIONS; i++) {
                explosions[i].active = false;
            }
        }
        return;
    }



    // 第一阶段暂无输入处理
    if (GetAsyncKeyState(VK_LEFT))
        playerX -= PLAYER_SPEED;
    if (GetAsyncKeyState(VK_RIGHT))
        playerX += PLAYER_SPEED;

    // 新增：空格键发射子弹
    if (GetAsyncKeyState(VK_SPACE) && bulletTimer == 0)
    {
        for (int i = 0; i < MAX_BULLETS; i++)
        {
            if (!bullets[i].alive)
            {
                // 精确计算子弹发射位置：
                // 1. 水平居中：飞机水平坐标X + 玩家飞机宽度的一半 - 子弹宽度的一半
                // 2. 垂直位置：飞机顶部 - 子弹高度（从飞机正前方发射）
                bullets[i].x = playerX + (playerWidth / 2) - (bulletWidth / 2);
                bullets[i].y = playerY - bulletHeight;

                bullets[i].alive = true;
                bulletTimer = 10; // 设置冷却时间
                break; // 一次只发射一颗子弹
            }
        }
    }

    // 新增：子弹冷却计时器递减
    if (bulletTimer > 0) bulletTimer--;
}

// ==== 边界检查 ====
void checkBoundaries()
{
    // 第一阶段暂无边界检查
        // 新增：防止飞机飞出屏幕
    if (playerX < 0) playerX = 0;
    if (playerX > WIDTH - playerWidth) playerX = WIDTH - playerWidth;
}

// ==== 更新游戏状态 ====
void updateGame()
{
    // 第一阶段暂无状态更新
     // 新增：更新子弹位置
    for (int i = 0; i < MAX_BULLETS; i++)
    {
        if (bullets[i].alive)
        {
            // 子弹向上移动
            bullets[i].y -= BULLET_SPEED;

            // 离开屏幕则回收子弹
            if (bullets[i].y < -30)
            {
                bullets[i].alive = false;
            }
        }
    }

    updateEnemies();

    updateExplosions();

    if (playerDying) {
        playerDeathFrame++;
        if (playerDeathFrame > 15) {
            gameOver = true;
            playerX = -100;
            playerY = -100;
        }
    }
}

// ==== 渲染游戏画面 ====
void renderGame()
{
    // 绘制背景
    putimage(0, 0, &img_background);
    // 新增：绘制玩家飞机
    drawAlpha(&img_player, playerX, playerY);

    // 新增：绘制子弹
    for (int i = 0; i < MAX_BULLETS; i++)
    {
        if (bullets[i].alive)
        {
            drawAlpha(&img_bullet, bullets[i].x, bullets[i].y);
        }
    }

    // 新增：绘制敌机
    for (int i = 0; i < MAX_ENEMIES; i++) {
        if (enemies[i].alive) {
            switch (enemies[i].type) {
            case ENEMY_SMALL:
                drawAlpha(&img_enemy_small, enemies[i].x, enemies[i].y);
                break;
            case ENEMY_MIDDLE:
                drawAlpha(&img_enemy_middle, enemies[i].x, enemies[i].y);
                break;
            case ENEMY_BIG:
                drawAlpha(&img_enemy_big, enemies[i].x, enemies[i].y);
                break;
            }

            // 显示生命值
            char hpInfo[20];
            sprintf_s(hpInfo, "HP:%d", enemies[i].hp);
            outtextxy(enemies[i].x, enemies[i].y - 15, hpInfo);
        }
    }

    for (int i = 0; i < MAX_EXPLOSIONS; i++)
    {
        if (explosions[i].active)
        {
            int frame = explosions[i].frame / 3;
            IMAGE* img = NULL;
            int imgWidth = 0;
            int imgHeight = 0;

            switch (explosions[i].type) {
            case ENEMY_SMALL:
                if (frame < 4) {
                    img = &img_explosion_small[frame];
                    imgWidth = img->getwidth();
                    imgHeight = img->getheight();
                }
                break;
            case ENEMY_MIDDLE:
                if (frame < 4) {
                    img = &img_explosion_middle[frame];
                    imgWidth = img->getwidth();
                    imgHeight = img->getheight();
                }
                break;
            case ENEMY_BIG:
                if (frame < 6) {
                    img = &img_explosion_big[frame];
                    imgWidth = img->getwidth();
                    imgHeight = img->getheight();
                }
                break;
            case 3: // 玩家飞机爆炸
                if (frame < 4) {
                    img = &img_player_death[frame];
                    imgWidth = img->getwidth();
                    imgHeight = img->getheight();
                }
                break;
            }
            if (img) {
                // 正确的爆炸位置计算
                int drawX = explosions[i].x - imgWidth / 2;
                int drawY = explosions[i].y - imgHeight / 2;
                drawAlpha(img, drawX, drawY);
            }
        }
    }
    // 显示游戏结束提示
    if (gameOver) {
        outtextxy(WIDTH / 2 - 80, HEIGHT / 2, "游戏结束！按R键重新开始");
    }

    cout << "sadfas" << endl;

    // 绘制玩家飞机或死亡动画
    if (!playerDying) {
        drawAlpha(&img_player, playerX, playerY);
    }
    else if (playerDeathFrame < 12) {
        int frame = playerDeathFrame / 3;
        if (frame > 3) frame = 3;
        drawAlpha(&img_player_death[frame], playerX, playerY);
    }

    char positionInfo[50];
    sprintf_s(positionInfo, "位置: (%d, %d)", playerX, playerY);
    outtextxy(10, 10, positionInfo);

    // 显示提示信息
    setbkmode(TRANSPARENT); // 设置文字背景透明

    // 新增：计算激活的子弹数量
    int activeBullets = 0;
    for (int i = 0; i < MAX_BULLETS; i++) {
        if (bullets[i].alive) activeBullets++;
    }

    // 新增：显示子弹信息
    char bulletInfo[50];
    sprintf_s(bulletInfo, sizeof(bulletInfo), "子弹: %d/%d", activeBullets, MAX_BULLETS);
    outtextxy(10, 30, bulletInfo);

    // 新增：更新操作提示
    outtextxy(10, 50, "方向键移动，空格发射子弹，ESC退出");

    char scoreInfo[50];
    sprintf_s(scoreInfo, "分数: %d", score);
    outtextxy(10, 70, scoreInfo);
    // 更新显示
    FlushBatchDraw();
}

// 透明贴图函数
void drawAlpha(IMAGE* picture, int picture_x, int picture_y)
{
    // 获取显存指针
    DWORD* dst = GetImageBuffer();
    DWORD* draw = GetImageBuffer();
    DWORD* src = GetImageBuffer(picture);

    int picture_width = picture->getwidth();
    int picture_height = picture->getheight();
    int graphWidth = getwidth();
    int graphHeight = getheight();
    int dstX = 0; // 在显存里的像素索引

    // 循环处理图像的每个像素
    for (int iy = 0; iy < picture_height; iy++)
    {
        for (int ix = 0; ix < picture_width; ix++)
        {
            int srcX = ix + iy * picture_width; // 源图像素索引

            // 从源图中提取ARGB值
            int sa = ((src[srcX] & 0xff000000) >> 24); // 透明度
            int sr = ((src[srcX] & 0xff0000) >> 16);  // 红色通道
            int sg = ((src[srcX] & 0xff00) >> 8);      // 绿色通道
            int sb = src[srcX] & 0xff;                 // 蓝色通道

            // 检查目标位置是否在屏幕范围内
            int targetX = ix + picture_x;
            int targetY = iy + picture_y;

            if (targetX >= 0 && targetX < graphWidth &&
                targetY >= 0 && targetY < graphHeight)
            {
                dstX = targetX + targetY * graphWidth;

                if (dstX < graphWidth * graphHeight) // 防止越界
                {
                    // 从目标位置提取当前颜色
                    int dr = ((dst[dstX] & 0xff0000) >> 16);
                    int dg = ((dst[dstX] & 0xff00) >> 8);
                    int db = dst[dstX] & 0xff;

                    // 计算混合后的颜色值
                    int r = (sr * sa / 255 + dr * (255 - sa) / 255);
                    int g = (sg * sa / 255 + dg * (255 - sa) / 255);
                    int b = (sb * sa / 255 + db * (255 - sa) / 255);

                    // 将混合后的颜色写回显存
                    draw[dstX] = (r << 16) | (g << 8) | b;
                }
            }
        }
    }
}

// 新增：子弹初始化函数
void initBullets()
{
    for (int i = 0; i < MAX_BULLETS; i++) {
        bullets[i].alive = false;
        bullets[i].x = -100; // 初始在屏幕外
        bullets[i].y = -100; // 初始在屏幕外
    }
}

// 新增：初始化敌机
void initEnemies() {
    for (int i = 0; i < MAX_ENEMIES; i++) {
        enemies[i].alive = false;
        enemies[i].x = -100;
        enemies[i].y = -100;
        enemies[i].speed = 0;
        enemies[i].type = ENEMY_SMALL;
        enemies[i].hp = 0;
        enemies[i].width = 0;
        enemies[i].height = 0;
    }
}

void spawnEnemy() {
    if (enemySpawnTimer > 0) {
        enemySpawnTimer--;
        return;
    }

    for (int i = 0; i < MAX_ENEMIES; i++) {
        if (!enemies[i].alive) {
            // 从屏幕上方生成敌机
            for (int i = 0; i < MAX_ENEMIES; i++) {
                if (!enemies[i].alive) {
                    enemies[i].type = rand() % 3;

                    switch (enemies[i].type) {
                    case ENEMY_SMALL:
                        enemies[i].width = 57;
                        enemies[i].height = 43;
                        enemies[i].hp = 1;
                        enemies[i].speed = 3 + rand() % 3;
                        break;
                    case ENEMY_MIDDLE:
                        enemies[i].width = 69;
                        enemies[i].height = 99;
                        enemies[i].hp = 2;
                        enemies[i].speed = 2 + rand() % 2;
                        break;
                    case ENEMY_BIG:
                        enemies[i].width = 169;
                        enemies[i].height = 258;
                        enemies[i].hp = 3;
                        enemies[i].speed = 1 + rand() % 2;
                        break;
                    }

                    enemies[i].x = rand() % (WIDTH - enemies[i].width);
                    enemies[i].y = -enemies[i].height;

                    enemies[i].alive = true;

                    // 重置生成计时器（30-60帧）
                    enemySpawnTimer = 30 + rand() % 30;
                    break;
                }
            }
        }
    }
}

// 新增：更新敌机
void updateEnemies() {
    // 更新敌机位置
    for (int i = 0; i < MAX_ENEMIES; i++) {
        if (enemies[i].alive) {
            enemies[i].y += enemies[i].speed; // 敌机向下移动

            // 敌机飞出屏幕则重置
            if (enemies[i].y > HEIGHT) {
                enemies[i].alive = false;
            }
        }
    }
    // 生成新敌机
    spawnEnemy();
}

void checkCollisions() {
    for (int i = 0; i < MAX_BULLETS; i++) {
        if (bullets[i].alive) {
            for (int j = 0; j < MAX_ENEMIES; j++) {
                if (enemies[j].alive) {
                    if (bullets[i].x < enemies[j].x + enemies[j].width &&
                        bullets[i].x + bulletWidth > enemies[j].x &&
                        bullets[i].y < enemies[j].y + enemies[j].height &&
                        bullets[i].y + bulletHeight > enemies[j].y) {

                        bullets[i].alive = false;
                        enemies[j].hp--;

                        if (enemies[j].hp <= 0) {
                            // 添加爆炸效果
                            spawnExplosion(
                                enemies[j].x + enemies[j].width / 2,
                                enemies[j].y + enemies[j].height / 2,
                                enemies[j].type
                            );

                            enemies[j].alive = false;

                            // 增加分数
                            score += (enemies[j].type + 1) * 10;
                        }
                    }
                }
            }
        }
    }
}

void spawnExplosion(int x, int y, int type) {
    for (int i = 0; i < MAX_EXPLOSIONS; i++) {
        if (!explosions[i].active) {
            explosions[i].x = x;
            explosions[i].y = y;
            explosions[i].frame = 0;
            explosions[i].active = true;
            explosions[i].type = type;
            return;
        }
    }
}

void updateExplosions() {
    for (int i = 0; i < MAX_EXPLOSIONS; i++) {
        if (explosions[i].active) {
            explosions[i].frame++;
            if (explosions[i].frame > 15) {
                explosions[i].active = false;
            }
        }
    }
}

void checkPlayerHit() {
    if (playerDying || gameOver) return;
    for (int i = 0; i < MAX_ENEMIES; i++) {
        if (enemies[i].alive) {
            // 玩家-敌机碰撞检测
            if (playerX < enemies[i].x + enemies[i].width &&
                playerX + playerWidth > enemies[i].x &&
                playerY < enemies[i].y + enemies[i].height &&
                playerY + playerHeight > enemies[i].y) {
                // 玩家被击中
                playerDying = true;
            }
        }
    }
}